/*******************************************************************************
 * Copyright (c) 2010 liw.
 * All rights reserved. 
 * 
 * This file is part of VanBus.
 * 
 *     VanBus is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     VanBus is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with VanBus.  If not, see <http://www.gnu.org/licenses/>.
 * Contributors:
 *     liw - initial API and implementation
 ******************************************************************************/
package org.niclab.vanbus.activity;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.client.ResponseHandler;
import org.niclab.vanbus.R;
import org.niclab.vanbus.activity.controller.BusRouteController;
import org.niclab.vanbus.application.VanBusApplication;
import org.niclab.vanbus.database.ApplicationDataBase;
import org.niclab.vanbus.database.BusRouteDAO;
import org.niclab.vanbus.model.BusRoute;
import org.niclab.vanbus.model.viewadpater.BusRouteExpandableListAdapter;
import org.niclab.vanbus.model.viewadpater.CommonBusRouteExpandableListAdapter;
import org.niclab.vanbus.model.viewadpater.CommonExpandableListAdapter;
import org.niclab.vanbus.model.viewadpater.CommonListAdapter;
import org.niclab.vanbus.query.BusDirQuery;
import org.niclab.vanbus.query.BusRouteQuery;
import org.niclab.vanbus.query.RouteStopsWithTimesQuery;
import org.niclab.vanbus.query.SimpleQueryWorker;
import org.niclab.vanbus.query.command.DismissDialogCmd;
import org.niclab.vanbus.query.command.ICommand;
import org.niclab.vanbus.query.command.ICommandChain;
import org.niclab.vanbus.query.command.PopulateRouteDirCmd;
import org.niclab.vanbus.query.command.ShowDialogCmd;
import org.niclab.vanbus.query.command.UpdateBusRouteListCmd;
import org.niclab.vanbus.query.command.UpdateListViewCmd;
import org.niclab.vanbus.query.handler.IQueryHandler;
import org.niclab.vanbus.query.mem.SimpleMemQueryHandler;
import org.niclab.vanbus.query.ws.RouteDirWSQueryResResolver;
import org.niclab.vanbus.query.ws.RouteWSQueryResResolver;
import org.niclab.vanbus.query.ws.SimpleWSQueryHandler;
import org.niclab.vanbus.query.ws.RouteDirWSQueryResResolver.QueryResult;
import org.niclab.vanbus.utils.CacheUtils;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ExpandableListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;

public class PickBusRouteExpandableAct extends ExpandableListActivity{
	
	//Dialogs
	private static final int DIALOG_GENERAL_BUSY = 0;
	private static final int DIALOG_NO_BUS_ROUTE_FOUND=1;
	private static final String LOG_TAG="PickBusRouteExpandableAct";
	
	
	//private Long listKey;
	private CommonExpandableListAdapter model;
	
	@SuppressWarnings("unchecked")
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		this.setTitle(R.string.pick_bus_route_title);
				
		//get the data;
		Intent intent = getIntent();
		String queryStr = intent.getStringExtra(getString(R.string.intent_currently_searched_bus_route_no));
		Log.d(LOG_TAG,"query string: "+queryStr);
		
		model = new CommonBusRouteExpandableListAdapter(this, R.layout.bus_route_row,R.layout.bus_route_dir_row);
		this.setListAdapter(model);
		
		startRetrieveBusRoutes(queryStr);

		
		
	}
	

	
	private void startRetrieveBusRoutes(String route){

				
		final BusRouteQuery query = new BusRouteQuery();
		query.addQueryInputParam(BusRouteQuery.InputParams.SEARCH_STR, route);
		
		SimpleQueryWorker worker = new SimpleQueryWorker();
	
		//set up PRE Execution commands
		//display a busy dialog
		ICommand sDialog = new ShowDialogCmd(this,DIALOG_GENERAL_BUSY);
		worker.addAsyncPreCommand(sDialog);
		
		//set up POST EXECUTION Commands
		
		ICommand populateModel = new ICommand() {

			@Override
			public void execute(Object input, ICommandChain chain) {
				RouteWSQueryResResolver.QueryResult result = (org.niclab.vanbus.query.ws.RouteWSQueryResResolver.QueryResult) query.getQueryResult();
				List<BusRoute> routes = result.getBusRoutes();
				BaseExpandableListAdapter expandableModel=new BusRouteExpandableListAdapter(model.getContext(), model.getGroupResourceId(), model.getChildResourceId(),routes);
				model.setDelegate(expandableModel);
				
				chain.execute(input);
			}
			
		};
		//dismiss a busy dialog
		ICommand dDialog = new DismissDialogCmd(this, DIALOG_GENERAL_BUSY);
		ICommand updateUI = new UpdateBusRouteListCmd(this);
		
		//possibly display an error window when no bus route found
		ICommand eDialog = new ShowDialogCmd(this, DIALOG_NO_BUS_ROUTE_FOUND);
		
		worker.addAsyncPostCommand(populateModel);
		worker.addAsyncPostCommand(dDialog);
		worker.addAsyncPostCommand(updateUI);
		worker.addAsyncPostCommand(eDialog);
		
		ResponseHandler resHandler = new RouteWSQueryResResolver();
		IQueryHandler wsQueryHandler = new SimpleWSQueryHandler(query, resHandler);
		
		worker.addAsyncQueryHandler(wsQueryHandler);
		//task.execute(new HttpRequestWorker<List<BusRoute>>(query, handler));
		Log.d(LOG_TAG,"start to retrieve bus routes");
		worker.work();
		
		
	}
	
	@Override
	protected Dialog onCreateDialog(int id){
		Dialog dialog;
		switch(id){
		
		case DIALOG_GENERAL_BUSY:
			ProgressDialog pDialog = new ProgressDialog(this);
			pDialog.setMessage(getString(R.string.dialog_loading_busy_msg));
			pDialog.setIndeterminate(true);
			dialog = pDialog;
			break;
		case DIALOG_NO_BUS_ROUTE_FOUND:
			AlertDialog.Builder aDialog= new AlertDialog.Builder(this);
			aDialog.setMessage(R.string.dialog_no_dir_found_msg);
			aDialog.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					
				}				
			});
			dialog = aDialog.create();
			break;
		default: dialog=null;
		
		
		}
		
		return dialog;
		
	}
	
	@Override
	public void onGroupExpand(final int groupPosition){
			
		final Context context = this.getApplicationContext();
		//currently selected bus route group
		final BusRoute route = (BusRoute)getExpandableListAdapter().getGroup(groupPosition);
		//fetch the bus route direction data

		final BusDirQuery query= new BusDirQuery();
		query.addQueryInputParam(BusDirQuery.InputParams.BUS_ROUTE_ID, route.getRouteId());

		SimpleQueryWorker worker = new SimpleQueryWorker();
		
		
		//set up PRE Execution commands
		//display a busy dialog
		ICommand sDialog = new ShowDialogCmd(this,DIALOG_GENERAL_BUSY);
		worker.addAsyncPreCommand(sDialog);
		
		//set up POST EXECUTION Commands
		//dismiss a busy dialog
		ICommand dDialog = new DismissDialogCmd(this, DIALOG_GENERAL_BUSY);

		ICommand updateUI = new UpdateBusRouteListCmd(this);
		
		//populate the busroute model
		ICommand populateModel = new ICommand(){

			@Override
			public void execute(Object input, ICommandChain chain) {
				List<BusRoute> result = (List<BusRoute>) query.getQueryResult();
				model.setChildrenList(groupPosition, result);
				//model.notifyDataSetChanged();			
				chain.execute(input);
			}
		};
		
		worker.addAsyncPostCommand(populateModel);
		worker.addAsyncPostCommand(dDialog);
		worker.addAsyncPostCommand(updateUI);
		
		//RouteDirWSQueryResResolver wsHandler = new RouteDirWSQueryResResolver(route, model, groupPosition);
		RouteDirWSQueryResResolver wsResolver = new RouteDirWSQueryResResolver();
		
		//if the selected routes have been populated before, do not need to fetch it from web/db again.	
		IQueryHandler mHandler = new SimpleMemQueryHandler(query){

			@Override
			public void query() {
				//if already populated, then do nothing
				if (model.getChildrenCount(groupPosition)>=0){
					
					query.setQueryFinished(true);
					return;
				}
				else if (getNextQueryHandler()!=null){
					getNextQueryHandler().query();
				}
				
				
			}
			
			
		};
		
		IQueryHandler qHandler = new SimpleWSQueryHandler(query, wsResolver){
			
			@Override
			public void onPostQuery(){
				
				RouteDirWSQueryResResolver.QueryResult result = (RouteDirWSQueryResResolver.QueryResult) query.getQueryResult();
				List<BusRoute> routes = result.getRoutes();
				List<BusRoute> newRoutes = new ArrayList<BusRoute>();

				BusRouteController routeCtr = new BusRouteController();
				for(BusRoute r: routes){
					
					BusRoute tempRoute = routeCtr.createBusRouteFromCache(route.getRouteId(), r.getRouteDir(), 
							route.getRouteName(), r.getRouteDirDesp());
								
					//put this bus route objec to cache
					CacheUtils.saveBusRouteToCache(tempRoute);
					newRoutes.add(tempRoute);
				}
				
				Log.v(LOG_TAG, "list size:"+newRoutes.size());
				
				//hit the database to see if these routes are favorite routes
				BusRouteDAO routeDAO = new BusRouteDAO(ApplicationDataBase.getSQLiteOpenHelper());
				routeDAO.checkFavoriteRoutes(newRoutes);
				
				query.setQueryResult(newRoutes);
							
			}
		};
		
		worker.addAsyncQueryHandler(qHandler);
		worker.addSyncQueryHandler(mHandler);
		worker.work();
		super.onGroupExpand(groupPosition);
			
	}
	
	@Override
	public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id){
		//pop the stop list activity
		//currently selected bus route
		BusRoute busRoute = (BusRoute) getExpandableListAdapter().getChild(groupPosition, childPosition);
		
		//register the currently selected bus route to have the be able to retrieve
		
		VanBusApplication app = (VanBusApplication)getApplication();
		String key=busRoute.getRouteId()+busRoute.getRouteDir();
		app.saveTempData(key, busRoute);
		
		//start the stops list activity
		Intent startStopListIntent = new Intent();
		startStopListIntent.setClass(this,StopListOfRouteAct.class);
		startStopListIntent.putExtra(getString(R.string.currently_selected_bus_route), key);
		
		this.startActivity(startStopListIntent);
		
		return true;
	}

}
